import dayjs from "dayjs";
import type { BackgroundMainContentMsg } from "@src/entries/background/utils/MsgFromToContent";
import { portNameList } from "@src/entries/background/utils/MsgFromToContent";
import { generateUniqueTimestamp } from "@src/utils/common";

export class MsgFromToBackground {
  port:chrome.runtime.Port
  portName = portNameList[0]

  private pendingRequests: Record<string, (response: any) => void> = {};

  heartbeatInterval:ReturnType<typeof setInterval> | undefined

  constructor() {
    this.port = chrome.runtime.connect({ name: this.portName})
    this.initEvent()
  }

  initEvent = () => {
    this.onDisconnect()
    this.onMsgListen()

    this.sendHeartbeat()
  }

  onDisconnect = () => {
    // 监听断开事件，清理定时器
    this.port.onDisconnect.addListener(() => {
      console.log(`${this.portName} 心跳连接断开`)
      clearInterval(this.heartbeatInterval)
    })
  }

  /** 定时发送心跳信号 */
  sendHeartbeat = () => {
    const {portName} = this

    const message:BackgroundMainContentMsg = {
      type: 'HEARTBEAT',
      timestamp: Date.now(),
      payload:{portName}
    }
    
    const intervalId = setInterval(() => {
      console.log(`${portName} sendHeartBeat`)
      this.sendMsgToBackground(message);
    }, 25*1000)

    this.heartbeatInterval = intervalId
  }

  /** 处理来自background的消息 */
  onMsgListen = () => {
    this.port.onMessage.addListener(this.backgroundOnMsg)
  }

  /** 只处理来自background的消息 */
  backgroundOnMsg = async (message: BackgroundMainContentMsg) => {
    const {type, timestamp, payload, msgId} = message

    if(msgId && this.pendingRequests?.[msgId]) {
      return this.pendingRequests[msgId](payload)
    }

    switch(type) {
      case 'HEARTBEAT': {
        console.log(`收到 tab ${this.portName} 心跳: 时间 ${dayjs(timestamp).format('YYYY-MM-DD HH:mm:ss')}`);
        break;
      }
      default:
        
      break;
    }
  }

   /** 发送消息到Background */
   sendMsgToBackground = (message:Omit<BackgroundMainContentMsg,'timestamp'> & {timestamp?:number}) => {
      message.timestamp = Date.now()
      this.port.postMessage(message)
   }

  /** 发送异步消息到Background */
  sendAsyncMsgToBackground = async (msg:Partial<BackgroundMainContentMsg>) => {
    const msgId = generateUniqueTimestamp()
    
    const message:BackgroundMainContentMsg = {
      payload:{},
      msgId,
      type: 'B_SAVEDATA',
      ...msg,
      timestamp: Date.now()
    }

    return new Promise((resolve) => {
      this.pendingRequests[msgId] = resolve

      this.sendMsgToBackground(message)
    })
  }

}
